package com.hrt.datasender.datasent.service.handler;

import org.jboss.netty.buffer.ChannelBuffer;
import org.jboss.netty.channel.Channel;
import org.jboss.netty.channel.ChannelHandlerContext;
import org.jboss.netty.handler.codec.frame.FrameDecoder;

import com.btcode.log.ILog;

//import com.hrt.datasender.main.AppStart;

import com.hrt.datasender.datasent.DataSender;

/**
 * 处理粘包拆包
 * 
 * @author gislin
 *
 */
public class MessageDecode extends FrameDecoder {
    
    private final int msgMinLength = 6;
    
    private final int dataLengthBit = 4;
    
    private final int msgPrefixLength = 6;
    
    private final int msgSuffixLength = 6;

    static ILog log;

    @Override
    protected Object decode(ChannelHandlerContext ctx, Channel channel, ChannelBuffer buffer) throws Exception {

        if (log == null) {
            log = DataSender.log;
        }

        // 为了解析得到报文的长度，必须要有6个字节，##+四位长度，如##0076，表示报文长度为76
        if (buffer.readableBytes() < msgMinLength) {
            return null;
        }

        byte[] dataStartByte = new byte[5];
        buffer.getBytes(0, dataStartByte, 0, 5);
        String dataStartStr = new String(dataStartByte);
        if("ST=91".equals(dataStartStr)){
            return null;
        }

        // 获取报文的长度
        byte[] dataLengthByte = new byte[dataLengthBit];
        // 当前已读取的指针位置
        int readIndex = buffer.readerIndex();
        // 获取长度部分报文的byte
        buffer.getBytes(readIndex + 2, dataLengthByte, 0, dataLengthBit);
        // 把长度部分报文的byte解析成string
        String dataLengthStr = new String(dataLengthByte);
        int dataLength = 0;

        try {
            // 把长度string解析成int，如果解析不成功，认为报文无效，清除掉
            dataLength = Integer.parseInt(dataLengthStr);
        }
        catch (Exception e) {
            buffer.clear();
            channel.close();
            log.error("解析长度失败", e);
            log.error("报文：" + getString(buffer));
            return null;
        }

        if (dataLength < 1) {
            buffer.clear();
            channel.close();
            log.error("长度小于1");
            log.error("报文：" + getString(buffer));
            return null;
        }
        int expectDataLength = msgPrefixLength + dataLength + msgSuffixLength;// ## + 四位长度 + 报文 +
                                                          // CRC验证码 + 回车换行符
        if (buffer.readableBytes() < expectDataLength) {
            // 获取的数据长度和期望的长度不匹配，说明数据还没有接受完整，返回null等待数据
            return null;
        }

        byte[] decoded = new byte[expectDataLength];
        buffer.readBytes(decoded);
        String msg = new String(decoded);
        return msg;
    }

    /**
     * 把channelBuffer里面的字节解析成字符返回 gislin 2015年12月4日
     * 
     * @param buffer
     * @return
     */
    public String getString(ChannelBuffer buffer) {
        byte[] tempByte = new byte[buffer.readableBytes()];
        buffer.getBytes(0, tempByte, 0, buffer.readableBytes());
        String tempStr = new String(tempByte);
        return tempStr;
    }

}
